package org.openkanban.server.dao.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.dozer.DozerBeanMapper;
import org.openkanban.server.dao.KanbanDao;
import org.openkanban.server.domain.Activity;
import org.openkanban.server.domain.Kanban;
import org.openkanban.server.service.UserService;
import org.openkanban.shared.dto.KanbanDto;
import org.openkanban.shared.dto.StatusDto;
import org.openkanban.shared.util.StatusCodes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 * jpa implementation of kanban data access object
 */
@Repository
public class KanbanDaoJpaImpl implements KanbanDao {

    @Autowired
    private UserService userService;

    @Autowired
    private DozerBeanMapper mapper;

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @Transactional
    public Kanban createKanban(String title, String description, String effort, Set<Long> kanbanUser) {
	Kanban newKanban = new Kanban();

	for (Long userId : kanbanUser) {
	    newKanban.getKanbanUser().add(userService.getUser(userId));
	}

	newKanban.setTitle(title);
	newKanban.setDescription(description);
	newKanban.setEffort(effort);

	entityManager.persist(newKanban);

	return newKanban;

    }

    @Override
    public Kanban getKanbanById(Long kanbanId) {
	return entityManager.find(Kanban.class, kanbanId);
    }

    @Override
    @Transactional
    public List<KanbanDto> getAllByActivityId(Long parentActivityId) {

	Activity parentActivity = entityManager.find(Activity.class, parentActivityId);
	if (parentActivity != null) {
	    List<Kanban> kanbanList = new ArrayList<Kanban>(parentActivity.getKanbans());

	    List<KanbanDto> kanbanDtoList = new ArrayList<KanbanDto>();
	    KanbanDto kanbanDto;
	    for (Kanban kanban : kanbanList) {
		kanbanDto = mapper.map(kanban, KanbanDto.class);
		kanbanDtoList.add(kanbanDto);
	    }

	    return kanbanDtoList;
	}

	return null;
    }

    @Override
    @Transactional
    public StatusDto removeKanban(Kanban kanbanToRemove) {
	entityManager.remove(kanbanToRemove);
	return new StatusDto(StatusCodes.OK);
    }

    @Override
    @Transactional
    public Kanban updateKanban(Kanban kanban) {
	return entityManager.merge(kanban);
    }

}
